Orange: monday merger with bf-blender (loadsa bugfixes).
[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 WIN32
42 #include "BLI_winstuff.h"
43 #endif
44
45 #include "MEM_guardedalloc.h"
46
47 #include "PIL_time.h"
48
49 #include "nla.h"        /* Only for the #ifdef flag - To be removed later */
50
51 #include "BLI_blenlib.h"
52 #include "BLI_arithb.h"
53
54 #include "DNA_object_types.h"
55 #include "DNA_screen_types.h"
56 #include "DNA_space_types.h"
57 #include "DNA_view3d_types.h"
58 #include "DNA_userdef_types.h"
59
60 #include "BKE_action.h"
61 #include "BKE_anim.h"
62 #include "BKE_blender.h"
63 #include "BKE_depsgraph.h"
64 #include "BKE_displist.h"
65 #include "BKE_global.h"
66 #include "BKE_image.h"
67 #include "BKE_ipo.h"
68 #include "BKE_key.h"
69 #include "BKE_scene.h"
70 #include "BKE_utildefines.h"
71
72 #include "BIF_butspace.h"
73 #include "BIF_editseq.h"
74 #include "BIF_editsound.h"
75 #include "BIF_editmesh.h"
76 #include "BIF_interface.h"
77 #include "BKE_object.h"
78 #include "BIF_poseobject.h"
79 #include "BIF_renderwin.h"
80 #include "BIF_screen.h"
81 #include "BIF_space.h"
82 #include "BIF_toets.h"
83 #include "BIF_toolbox.h"
84 #include "BIF_usiblender.h"
85
86 #include "BDR_vpaint.h"
87 #include "BDR_editobject.h"
88 #include "BDR_editface.h"
89
90 #include "BSE_filesel.h"        /* For activate_fileselect */
91 #include "BSE_drawview.h"       /* For play_anim */
92 #include "BSE_view.h"
93 #include "BSE_edit.h"
94 #include "BSE_editipo.h"
95 #include "BSE_headerbuttons.h"
96 #include "BSE_seqaudio.h"
97
98 #include "blendef.h"
99 #include "render.h"             // darn schrijfplaatje() (ton)
100
101 #include "IMB_imbuf.h"
102 #include "IMB_imbuf_types.h"
103
104 #include "mydevice.h"
105
106 #include "BIF_poseobject.h"
107
108 /* only used in toets.c and initrender.c */
109 /* this function doesn't really belong here */
110 /* ripped from render module */
111 void schrijfplaatje(char *name);
112
113
114 static void write_imag(char *name)
115 {
116         /* from file select */
117         char str[256];
118
119         /* addImageExtension() checks for if extension was already set */
120         if(G.scene->r.scemode & R_EXTENSION) 
121                 if(strlen(name)<FILE_MAXDIR+FILE_MAXFILE-5)
122                         addImageExtension(name);
123         
124         strcpy(str, name);
125         BLI_convertstringcode(str, G.sce, G.scene->r.cfra);
126
127         if(saveover(str)) {
128                 if(BLI_testextensie(str,".blend")) {
129                         error("Wrong filename");
130                         return;
131                 }
132                 waitcursor(1); /* from screen.c */
133                 schrijfplaatje(str);
134                 strcpy(G.ima, name);
135                 waitcursor(0);
136         }
137 }
138
139
140 /* From matrix.h: it's really a [4][4]! */
141 /* originally in initrender... maybe add fileControl thingy? */
142
143 /* should be called write_image(char *name) :-) */
144 void schrijfplaatje(char *name)
145 {
146         struct ImBuf *ibuf=0;
147         unsigned int *temprect=0;
148         char str[FILE_MAXDIR+FILE_MAXFILE];
149
150         /* radhdr: temporary call for direct float buffer save for HDR format */
151         if ((R.r.imtype==R_RADHDR) && (R.rectftot))
152         {
153                 imb_savehdr_fromfloat(R.rectftot, name, R.rectx, R.recty);
154                 return;
155         }
156
157         /* has RGBA been set? If so: use alpha channel for color zero */
158         IMB_alpha_to_col0(FALSE);
159
160         if(R.r.planes == 32) {
161                 /* everything with less than 50 % alpha -> col 0 */
162                 if(R.r.alphamode == R_ALPHAKEY) IMB_alpha_to_col0(2);
163                 /* only when 0 alpha -> col 0 */
164                 else IMB_alpha_to_col0(1);
165         }
166
167         /* Seems to me this is also superfluous.... */
168         if (R.r.imtype==R_FTYPE) {
169                 strcpy(str, R.r.ftype);
170                 BLI_convertstringcode(str, G.sce, G.scene->r.cfra);
171
172                 ibuf = IMB_loadiffname(str, IB_test);
173                 if(ibuf) {
174                         ibuf->x = R.rectx;
175                         ibuf->y = R.recty;
176                 }
177                 else {
178                         error("Can't find filetype");
179                         G.afbreek= 1;
180                         return;
181                 }
182                 /* setdither(2); */
183         }
184
185         if(ibuf == 0) {
186                 ibuf= IMB_allocImBuf(R.rectx, R.recty, (char) R.r.planes, 0, 0);
187         }
188
189         if(ibuf) {
190                 ibuf->rect= (unsigned int *) R.rectot;
191 //              ibuf->rect_float = R.rectftot;
192
193                 if(R.r.planes == 8) IMB_cspace(ibuf, rgb_to_bw);
194
195                 if(R.r.imtype== R_IRIS) {
196                         ibuf->ftype= IMAGIC;
197                 }
198                 else if(R.r.imtype==R_IRIZ) {
199                         ibuf->ftype= IMAGIC;
200                         if (ibuf->zbuf == 0) {
201                                 if (R.rectz) {
202                                         ibuf->zbuf = (int *)R.rectz;
203                                 }
204                                 else printf("no zbuf\n");
205                         }
206                 }
207                 else if(R.r.imtype==R_RADHDR) {
208                         /* radhdr: save hdr from rgba buffer, not really recommended, probably mistake, so warn user */
209                         error("Will save, but you might want to enable the floatbuffer to save a real HDRI...");
210                         ibuf->ftype= RADHDR;
211                 }
212                 else if(R.r.imtype==R_PNG) {
213                         ibuf->ftype= PNG;
214                 }
215                 else if(R.r.imtype==R_BMP) {
216                         ibuf->ftype= BMP;
217                 }
218                 else if((G.have_libtiff) && (R.r.imtype==R_TIFF)) {
219                         ibuf->ftype= TIF;
220                 }
221                 else if((R.r.imtype==R_TARGA) || (R.r.imtype==R_PNG)) {
222                         ibuf->ftype= TGA;
223                 }
224                 else if(R.r.imtype==R_RAWTGA) {
225                         ibuf->ftype= RAWTGA;
226                 }
227                 else if(R.r.imtype==R_HAMX) {
228                         /* make copy */
229                         temprect= MEM_dupallocN(R.rectot);
230                         ibuf->ftype= AN_hamx;
231                 }
232                 else if(ELEM5(R.r.imtype, R_MOVIE, R_AVICODEC, R_AVIRAW, R_AVIJPEG, R_JPEG90)) {
233                         if(R.r.quality < 10) R.r.quality= 90;
234
235                         if(R.r.mode & R_FIELDS) ibuf->ftype= JPG_VID|R.r.quality;
236                         else ibuf->ftype= JPG|R.r.quality;
237                 }
238         
239                 RE_make_existing_file(name);
240
241                 if(IMB_saveiff(ibuf, name, IB_rect | IB_zbuf)==0) {
242                         perror(name);
243                         G.afbreek= 1;
244                 }
245
246                 IMB_freeImBuf(ibuf);
247
248                 if (R.r.imtype==R_HAMX) {
249                         MEM_freeN(R.rectot);
250                         R.rectot= temprect;
251                 }
252         }
253         else {
254                 G.afbreek= 1;
255         }
256 }
257
258
259
260 /* ------------------------------------------------------------------------- */
261
262 static int is_an_active_object(void *ob) {
263         Base *base;
264         
265         for (base= FIRSTBASE; base; base= base->next)
266                 if (base->object == ob)
267                         return 1;
268         
269         return 0;
270 }
271
272 void persptoetsen(unsigned short event)
273 {
274         static Object *oldcamera=0;
275         float phi, si, q1[4], vec[3];
276         static int perspo=1;
277         
278         if(event==PADENTER) {
279                 if (G.qual == LR_SHIFTKEY) {
280                         view3d_set_1_to_1_viewborder(G.vd);
281                 } else {
282                         if (G.vd->persp==2) {
283                                 G.vd->camzoom= 0;
284                         } else {
285                                 G.vd->dist= 10.0;
286                         }
287                 }
288         }
289         else if((G.qual & (LR_SHIFTKEY | LR_CTRLKEY)) && (event != PAD0)) {
290                 if(event==PAD0) {
291                         /* G.vd->persp= 3; */
292                 }
293                 else if(event==PAD7) {
294                         G.vd->viewquat[0]= 0.0;
295                         G.vd->viewquat[1]= -1.0;
296                         G.vd->viewquat[2]= 0.0;
297                         G.vd->viewquat[3]= 0.0;
298                         G.vd->view= 7;
299                         if (U.uiflag & USER_AUTOPERSP) G.vd->persp= 0; 
300                         else if(G.vd->persp>=2) G.vd->persp= perspo;
301                 }
302                 else if(event==PAD1) {
303                         G.vd->viewquat[0]= 0.0;
304                         G.vd->viewquat[1]= 0.0;
305                         G.vd->viewquat[2]= (float)-cos(M_PI/4.0);
306                         G.vd->viewquat[3]= (float)-cos(M_PI/4.0);
307                         G.vd->view=1;
308                         if (U.uiflag & USER_AUTOPERSP) G.vd->persp= 0;
309                         else if(G.vd->persp>=2) G.vd->persp= perspo;
310                 }
311                 else if(event==PAD3) {
312                         G.vd->viewquat[0]= 0.5;
313                         G.vd->viewquat[1]= -0.5;
314                         G.vd->viewquat[2]= 0.5;
315                         G.vd->viewquat[3]= 0.5;
316                         G.vd->view=3;
317                         if (U.uiflag & USER_AUTOPERSP) G.vd->persp= 0;
318                         else if(G.vd->persp>=2) G.vd->persp= perspo;
319                 }
320                 else if(event==PADMINUS) {
321                         /* this min and max is also in viewmove() */
322                         if(G.vd->persp==2) {
323                                         G.vd->camzoom-= 10;
324                                         if(G.vd->camzoom<-30) G.vd->camzoom= -30;
325                                 }
326                         else if(G.vd->dist<10.0*G.vd->far) G.vd->dist*=1.2f;
327                 }
328                 else if(event==PADPLUSKEY) {
329                         if(G.vd->persp==2) {
330                                         G.vd->camzoom+= 10;
331                                         if(G.vd->camzoom>300) G.vd->camzoom= 300;
332                         }
333                         else if(G.vd->dist> 0.001*G.vd->grid) G.vd->dist*=.83333f;
334                 }
335                 else {
336
337                         initgrabz(0.0, 0.0, 0.0);
338                         
339                         if(event==PAD6) window_to_3d(vec, -32, 0);
340                         else if(event==PAD4) window_to_3d(vec, 32, 0);
341                         else if(event==PAD8) window_to_3d(vec, 0, -25);
342                         else if(event==PAD2) window_to_3d(vec, 0, 25);
343                         G.vd->ofs[0]+= vec[0];
344                         G.vd->ofs[1]+= vec[1];
345                         G.vd->ofs[2]+= vec[2];
346                 }
347         }
348         else {
349
350                 if(event==PAD7) {
351                         G.vd->viewquat[0]= 1.0;
352                         G.vd->viewquat[1]= 0.0;
353                         G.vd->viewquat[2]= 0.0;
354                         G.vd->viewquat[3]= 0.0;
355                         G.vd->view=7;
356                         if (U.uiflag & USER_AUTOPERSP) G.vd->persp= 0;
357                         else if(G.vd->persp>=2) G.vd->persp= perspo;
358                 }
359                 else if(event==PAD1) {
360                         G.vd->viewquat[0]= (float)cos(M_PI/4.0);
361                         G.vd->viewquat[1]= (float)-sin(M_PI/4.0);
362                         G.vd->viewquat[2]= 0.0;
363                         G.vd->viewquat[3]= 0.0;
364                         G.vd->view=1;
365                         if (U.uiflag & USER_AUTOPERSP) G.vd->persp= 0;
366                         else if(G.vd->persp>=2) G.vd->persp= perspo;
367                 }
368                 else if(event==PAD3) {
369                         G.vd->viewquat[0]= 0.5;
370                         G.vd->viewquat[1]= -0.5;
371                         G.vd->viewquat[2]= -0.5;
372                         G.vd->viewquat[3]= -0.5;
373                         G.vd->view=3;
374                         if (U.uiflag & USER_AUTOPERSP) G.vd->persp= 0;
375                         else if(G.vd->persp>=2) G.vd->persp= perspo;
376                 }
377                 else if(event==PADMINUS) {
378                         /* this min and max is also in viewmove() */
379                         if(G.vd->persp==2) {
380                                 G.vd->camzoom= MAX2(-30, G.vd->camzoom-5);
381                         }
382                         else if(G.vd->dist<10.0*G.vd->far) G.vd->dist*=1.2f;
383                 }
384                 else if(event==PADPLUSKEY) {
385                         if(G.vd->persp==2) {
386                                 G.vd->camzoom= MIN2(300, G.vd->camzoom+5);
387                         }
388                         else if(G.vd->dist> 0.001*G.vd->grid) G.vd->dist*=.83333f;
389                 }
390                 else if(event==PAD5) {
391                         if(G.vd->persp==1) G.vd->persp=0;
392                         else G.vd->persp=1;
393                 }
394                 else if(event==PAD0) {
395                         if(G.qual==LR_ALTKEY) {
396                                 if(oldcamera && is_an_active_object(oldcamera)) {
397                                         G.vd->camera= oldcamera;
398                                 }
399                                 
400                                 handle_view3d_lock();
401                         }
402                         else if(BASACT) {
403                                 if(G.qual==LR_CTRLKEY) {
404                                         if(G.vd->camera != OBACT) {
405                                                 if(G.vd->camera && G.vd->camera->type==OB_CAMERA)
406                                                         oldcamera= G.vd->camera;
407                                                 
408                                                 G.vd->camera= OBACT;
409                                                 handle_view3d_lock();
410                                         }
411                                 }
412                                 else if(G.vd->camera==0 && OBACT->type==OB_CAMERA) {
413                                         G.vd->camera= OBACT;
414                                         handle_view3d_lock();
415                                 }
416                         }
417                         if(G.vd->camera==0) {
418                                 G.vd->camera= scene_find_camera(G.scene);
419                                 handle_view3d_lock();
420                         }
421                         
422                         if(G.vd->camera) {
423                                 G.vd->persp= 2;
424                                 G.vd->view= 0;
425                                 if(((G.qual & LR_CTRLKEY) && (G.qual & LR_ALTKEY)) || (G.qual & LR_SHIFTKEY)) {
426                                         void setcameratoview3d(void);   // view.c
427                                         setcameratoview3d();
428                                         DAG_object_flush_update(G.scene, G.scene->camera, OB_RECALC_OB);
429                                         allqueue(REDRAWVIEW3D, 0);
430                                 }                               
431                         }
432                 }
433                 else if(event==PAD9) {
434                         countall();
435                         update_for_newframe();
436                         
437                         reset_slowparents();    /* editobject.c */
438                 }
439                 else if(G.vd->persp<2) {
440                         if(event==PAD4 || event==PAD6) {
441                                 /* z-axis */
442                                 phi= (float)(M_PI/24.0);
443                                 if(event==PAD6) phi= -phi;
444                                 si= (float)sin(phi);
445                                 q1[0]= (float)cos(phi);
446                                 q1[1]= q1[2]= 0.0;
447                                 q1[3]= si;
448                                 QuatMul(G.vd->viewquat, G.vd->viewquat, q1);
449                                 G.vd->view= 0;
450                         }
451                         if(event==PAD2 || event==PAD8) {
452                                 
453                                 /* horizontal axis */
454                                 VECCOPY(q1+1, G.vd->viewinv[0]);
455                                 
456                                 Normalise(q1+1);
457                                 phi= (float)(M_PI/24.0);
458                                 if(event==PAD2) phi= -phi;
459                                 si= (float)sin(phi);
460                                 q1[0]= (float)cos(phi);
461                                 q1[1]*= si;
462                                 q1[2]*= si;
463                                 q1[3]*= si;
464                                 QuatMul(G.vd->viewquat, G.vd->viewquat, q1);
465                                 G.vd->view= 0;
466                         }
467                 }
468
469                 if(G.vd->persp<2) perspo= G.vd->persp;
470         }
471         scrarea_queue_redraw(curarea);
472 }
473
474 int untitled(char * name)
475 {
476         if (G.save_over == 0 ) {
477                 char * c= BLI_last_slash(name);
478                 
479                 if (c)
480                         strcpy(&c[1], "untitled.blend");
481                 else
482                         strcpy(name, "untitled.blend");
483                         
484                 return(TRUE);
485         }
486         
487         return(FALSE);
488 }
489
490 int save_image_filesel_str(char *str)
491 {
492         switch(G.scene->r.imtype) {
493         case R_RADHDR:
494                 strcpy(str, "Save Radiance HDR"); return 1;
495         case R_PNG:
496                 strcpy(str, "Save PNG"); return 1;
497         case R_BMP:
498                 strcpy(str, "Save BMP"); return 1;
499         case R_TIFF:
500                 if (G.have_libtiff) {
501                         strcpy(str, "Save TIFF"); return 1;
502                 }
503         case R_TARGA:
504                 strcpy(str, "Save Targa"); return 1;
505         case R_RAWTGA:
506                 strcpy(str, "Save Raw Targa"); return 1;
507         case R_IRIS:
508                 strcpy(str, "Save IRIS"); return 1;
509         case R_IRIZ:
510                 strcpy(str, "Save IRIS"); return 1;
511         case R_HAMX:
512                 strcpy(str, "Save HAMX"); return 1;
513         case R_FTYPE:
514                 strcpy(str, "Save Ftype"); return 1;
515         case R_JPEG90:
516                 strcpy(str, "Save JPEG"); return 1;
517         default:
518                 strcpy(str, "Save Image"); return 0;
519         }       
520 }
521
522 void BIF_save_rendered_image(void)
523 {
524         if(!R.rectot) {
525                 error("No image rendered");
526         } else {
527                 char dir[FILE_MAXDIR * 2], str[FILE_MAXFILE * 2];
528
529                 if(G.ima[0]==0) {
530                         strcpy(dir, G.sce);
531                         BLI_splitdirstring(dir, str);
532                         strcpy(G.ima, dir);
533                 }
534                 
535                 R.r.imtype= G.scene->r.imtype;
536                 R.r.quality= G.scene->r.quality;
537                 R.r.planes= G.scene->r.planes;
538         
539                 if (!save_image_filesel_str(str)) {
540                         error("Select an image type in DisplayButtons(F10)");
541                 } else {
542                         activate_fileselect(FILE_SPECIAL, str, G.ima, write_imag);
543                 }
544         }
545 }
546
547 int blenderqread(unsigned short event, short val)
548 {
549         /* here do the general keys handling (not screen/window/space) */
550         /* return 0: do not pass on to the other queues */
551         extern int textediting;
552         extern void playback_anim();
553         ScrArea *sa;
554         Object *ob;
555         int textspace=0;
556         /* Changed str and dir size to 160, to make sure there is enough
557          * space for filenames. */
558         char dir[FILE_MAXDIR * 2], str[FILE_MAXFILE * 2];
559         
560         if(val==0) return 1;
561         if(event==MOUSEY || event==MOUSEX) return 1;
562         if (G.flags & G_FILE_AUTOPLAY) return 1;
563
564         if (curarea && curarea->spacetype==SPACE_TEXT) textspace= 1;
565         else if (curarea && curarea->spacetype==SPACE_SCRIPT) textspace= 1;
566
567         switch(event) {
568
569         case F1KEY:
570                 if(G.qual==0) {
571                         /* this exception because of the '?' button */
572                         if(curarea->spacetype==SPACE_INFO) {
573                                 sa= closest_bigger_area();
574                                 areawinset(sa->win);
575                         }
576                         
577                         activate_fileselect(FILE_BLENDER, "Open File", G.sce, BIF_read_file);
578                         return 0;
579                 }
580                 else if(G.qual==LR_SHIFTKEY) {
581                         activate_fileselect(FILE_LOADLIB, "Load Library", G.lib, 0);
582                         return 0;
583                 }
584                 break;
585         case F2KEY:
586                 if(G.qual==0) {
587                         strcpy(dir, G.sce);
588                         untitled(dir);
589                         activate_fileselect(FILE_BLENDER, "Save File", dir, BIF_write_file);
590                         return 0;
591                 }
592                 else if(G.qual==LR_CTRLKEY) {
593                         write_vrml_fs();
594                         return 0;
595                 }
596                 else if(G.qual==LR_SHIFTKEY) {
597                         write_dxf_fs();
598                         return 0;
599                 }
600                 break;
601         case F3KEY:
602                 if(G.qual==0) {
603                         BIF_save_rendered_image();
604                         return 0;
605                 }
606                 else if(G.qual & LR_CTRLKEY) {
607                         /* all alt+ctrl+shift combos are needed here... */
608                         BIF_screendump(0);
609                 }
610                 break;
611         case F4KEY:
612                 if(G.qual==LR_SHIFTKEY) {
613
614                         memset(str, 0, 16);
615                         ob= OBACT;
616                         if(ob) strcpy(str, ob->id.name);
617
618                         activate_fileselect(FILE_MAIN, "Data Select", str, 0);
619                         return 0;
620                 }
621                 else if(G.qual==0) {
622                         extern_set_butspace(event);
623                 }
624                 break;
625         case F5KEY:
626                 if(G.qual==LR_SHIFTKEY) {
627                         newspace(curarea, SPACE_VIEW3D);
628                         return 0;
629                 }
630                 else if(G.qual==0) {
631                         extern_set_butspace(event);
632                 }
633                 break;
634         case F6KEY:
635                 if(G.qual==LR_SHIFTKEY) {
636                         newspace(curarea, SPACE_IPO);
637                         return 0;
638                 }
639                 else if(G.qual==0) {
640                         extern_set_butspace(event);
641                 }
642                 break;
643         case F7KEY:
644                 if(G.qual==LR_SHIFTKEY) {
645                         newspace(curarea, SPACE_BUTS);
646                         return 0;
647                 }
648                 else if(G.qual==0) {
649                         extern_set_butspace(event);
650                 }
651                 break;
652         case F8KEY:
653                 if(G.qual==LR_SHIFTKEY) {
654                         newspace(curarea, SPACE_SEQ);
655                         return 0;
656                 }
657                 else if(G.qual==0) {
658                         extern_set_butspace(event);
659                 }
660                 break;
661         case F9KEY:
662                 if(G.qual==LR_SHIFTKEY) {
663                         newspace(curarea, SPACE_OOPS);
664                         return 0;
665                 }
666                 else if(G.qual==(LR_SHIFTKEY|LR_ALTKEY)) {
667                         newspace(curarea, SPACE_OOPS+256);
668                         return 0;
669                 }
670                 else if(G.qual==0) {
671                         extern_set_butspace(event);
672                 }
673                 break;
674         case F10KEY:
675                 if(G.qual==LR_SHIFTKEY) {
676                         newspace(curarea, SPACE_IMAGE);
677                         return 0;
678                 }
679                 else if(G.qual==0) {
680                         extern_set_butspace(event);
681                 }
682                 break;
683         case F11KEY:
684                 if(G.qual==LR_SHIFTKEY) {
685                         newspace(curarea, SPACE_TEXT);
686                         return 0;
687                 }
688                 else if (G.qual==LR_CTRLKEY) {
689                         playback_anim();
690                 }
691                 else if(G.qual==0) {
692                         BIF_toggle_render_display();
693                         return 0;
694                 }
695                 break;
696         case F12KEY:
697                 if(G.qual==LR_SHIFTKEY) {
698                         newspace(curarea, SPACE_ACTION);
699                         return 0;
700                 }
701                 else if (G.qual==(LR_SHIFTKEY|LR_CTRLKEY)) {
702                         newspace(curarea, SPACE_NLA);
703                         return 0;
704                 }
705                 else if (G.qual==LR_CTRLKEY) {
706                         BIF_do_render(1);
707                 }
708                 else {
709                         /* ctrl/alt + f12 should render too, for some macs have f12 assigned to cd eject */
710                         BIF_do_render(0);
711                 }
712                 return 0;
713                 break;
714         
715         case WHEELUPMOUSE:
716                 if(G.qual==LR_ALTKEY || G.qual==LR_COMMANDKEY) {
717                         if(CFRA>1) {
718                                 CFRA--;
719                                 update_for_newframe();
720                         }
721                         return 0;
722                 }
723                 break;
724         case WHEELDOWNMOUSE:
725                 if(G.qual==LR_ALTKEY || G.qual==LR_COMMANDKEY) {
726                         CFRA++;
727                         update_for_newframe();
728                         return 0;
729                 }
730                 break;
731                 
732         case LEFTARROWKEY:
733         case DOWNARROWKEY:
734                 if(textediting==0 && textspace==0) {
735
736 #if 0
737 //#ifdef _WIN32 // FULLSCREEN
738                         if(event==DOWNARROWKEY){
739                                 if (G.qual==LR_ALTKEY)
740                                         mainwindow_toggle_fullscreen(0);
741                                 else if(G.qual==0)
742                                         CFRA-= 10;
743                         }
744 #else
745                         if((event==DOWNARROWKEY)&&(G.qual==0))
746                                 CFRA-= 10;
747 #endif
748                         else if((event==LEFTARROWKEY)&&(G.qual==0))
749                                 CFRA--;
750                         
751                         if(G.qual==LR_SHIFTKEY)
752                                 CFRA= SFRA;
753                         if(CFRA<1) CFRA=1;
754         
755                         update_for_newframe();
756                         return 0;
757                 }
758                 break;
759
760         case RIGHTARROWKEY:
761         case UPARROWKEY:
762                 if(textediting==0 && textspace==0) {
763
764 #if 0
765 //#ifdef _WIN32 // FULLSCREEN
766                         if(event==UPARROWKEY){ 
767                                 if(G.qual==LR_ALTKEY)
768                                         mainwindow_toggle_fullscreen(1);
769                                 else if(G.qual==0)
770                                         CFRA+= 10;
771                         }
772 #else
773                         if((event==UPARROWKEY)&&(G.qual==0))
774                                 CFRA+= 10;
775 #endif
776                         else if((event==RIGHTARROWKEY)&&(G.qual==0))
777                                 CFRA++;
778
779                         if(G.qual==LR_SHIFTKEY)
780                                 CFRA= EFRA;
781                         
782                         update_for_newframe();
783                 }
784                 break;
785
786         case ESCKEY:
787                 sound_stop_all_sounds();        // whats this?
788                 
789                 /* stop playback on ESC always */
790                 rem_screenhandler(G.curscreen, SCREEN_HANDLER_ANIM);
791                 audiostream_stop();
792                 allqueue(REDRAWALL, 0);
793                 
794                 break;
795         case TABKEY:
796                 if(G.qual==0) {
797                         if(textspace==0) {
798                                 if(curarea->spacetype==SPACE_IPO)
799                                         set_editflag_editipo();
800                                 else if(curarea->spacetype==SPACE_SEQ)
801                                         enter_meta();
802                                 else if(G.vd) {
803                                         /* also when Alt-E */
804                                         if(G.obedit==NULL) {
805                                                 enter_editmode();
806                                                 if(G.obedit) BIF_undo_push("Original"); // here, because all over code enter_editmode is abused
807                                         }
808                                         else
809                                                 exit_editmode(2); // freedata, and undo
810                                 }
811                                 return 0;
812                         }
813                 }
814                 else if(G.qual==LR_CTRLKEY){
815                         Object *ob= OBACT;
816                         if(ob) {
817                                 if(ob->type==OB_ARMATURE) {
818                                         if(ob->flag & OB_POSEMODE) exit_posemode();
819                                         else enter_posemode();
820                                 }
821                                 else if(ob->type==OB_MESH) {
822                                         if(ob==G.obedit) EM_selectmode_menu();
823                                         else set_wpaint();
824                                 }
825                         }
826                 }
827                 else if(G.qual==LR_SHIFTKEY) {  // ??
828                         if(G.obedit)
829                                 exit_editmode(2); // freedata, and undo
830                         if(G.f & G_FACESELECT)
831                                 set_faceselect();
832                         if(G.f & G_VERTEXPAINT)
833                                 set_vpaint();
834                         if(G.f & G_TEXTUREPAINT) {
835                                 G.f &= ~G_TEXTUREPAINT;
836                                 allqueue(REDRAWVIEW3D, 0);
837                                 allqueue(REDRAWBUTSEDIT, 0);
838                         }
839                         if(G.f & G_WEIGHTPAINT)
840                                 set_wpaint();
841                 }
842                 break;
843
844         case BACKSPACEKEY:
845                 break;
846
847         case AKEY:
848                 if(textediting==0 && textspace==0) {
849                         if(G.qual==(LR_SHIFTKEY|LR_ALTKEY)){
850                                 play_anim(1);
851                                 return 0;
852                         }
853                         else if(G.qual==LR_ALTKEY) {
854                                 play_anim(0);
855                                 return 0;
856                         }
857                 }
858                 break;
859         case EKEY:
860                 if(G.qual==LR_ALTKEY) {
861                         if(G.vd && textspace==0) {
862                                 if(G.obedit==0) {
863                                         enter_editmode();
864                                         BIF_undo_push("Original");
865                                 }
866                                 else
867                                         exit_editmode(2); // freedata, and undo
868                                 return 0;
869                         }                       
870                 }
871                 break;
872         case IKEY:
873                 if(textediting==0 && textspace==0 && curarea->spacetype!=SPACE_FILE && curarea->spacetype!=SPACE_IMASEL) {
874                         if(G.qual==0) {
875                                 common_insertkey();
876                                 return 0;
877                         }
878                 }
879                 break;
880         case JKEY:
881                 if(textediting==0 && textspace==0) {
882                         if(R.rectot && G.qual==0) {
883                                 BIF_swap_render_rects();
884                                 return 0;
885                         }
886                 }
887                 break;
888
889         case NKEY:
890                 if(textediting==0 && textspace==0) {
891                         if(G.qual & LR_CTRLKEY);
892                         else if(G.qual==0 || (G.qual & LR_SHIFTKEY)) {
893                                 if(curarea->spacetype==SPACE_VIEW3D);           // is new panel, in view3d queue
894                                 else if(curarea->spacetype==SPACE_IPO);                 // is new panel, in ipo queue
895                                 else if(curarea->spacetype==SPACE_IMAGE);                       // is new panel, in ipo queue
896                                 else if(curarea->spacetype==SPACE_ACTION);                      // is own queue
897                                 else if(curarea->spacetype==SPACE_NLA);                 // is new panel
898                                 else if(curarea->spacetype==SPACE_SEQ);                 // is new panel
899                                 else {
900                                         clever_numbuts();
901                                         return 0;
902                                 }
903                         }
904                 }
905                 break;
906                 
907         case OKEY:
908                 if(textediting==0) {
909                         if(G.qual==LR_CTRLKEY) {
910                                 /* There seem to be crashes here sometimes.... String
911                                  * bound overwrites? I changed dir and str sizes,
912                                  * let's see if this reoccurs. */
913                                 sprintf(str, "Open file: %s", G.sce);
914                         
915                                 if(okee(str)) {
916                                         strcpy(dir, G.sce);
917                                         BIF_read_file(dir);
918                                 }
919                                 return 0;
920                         }
921                 }
922                 break;
923                 
924         case SKEY:
925                 if(G.obedit==NULL) {
926                         if(G.qual==LR_CTRLKEY) {
927                                 strcpy(dir, G.sce);
928                                 if (untitled(dir)) {
929                                         activate_fileselect(FILE_BLENDER, "Save File", dir, BIF_write_file);
930                                 } else {
931                                         BIF_write_file(dir);
932                                         free_filesel_spec(dir);
933                                 }
934                                 return 0;
935                         }
936                 }
937                 break;
938         
939         case TKEY:
940                 if (G.qual==(LR_SHIFTKEY|LR_ALTKEY|LR_CTRLKEY)) {
941                         Object *ob = OBACT;
942                         int event = pupmenu(ob?"Time%t|draw|recalc ob|recalc data":"Time%t|draw");
943                         int a;
944                         double delta, stime;
945
946                         waitcursor(1);
947                         
948                         stime= PIL_check_seconds_timer();
949                         for(a=0; a<100000; a++) {
950                                 if (event==1) {
951                                         scrarea_do_windraw(curarea);
952                                 } else if (event==2) {
953                                         ob->recalc |= OB_RECALC_OB;
954                                         object_handle_update(ob);
955                                 } else if (event==3) {
956                                         ob->recalc |= OB_RECALC_DATA;
957                                         object_handle_update(ob);
958                                 }
959
960                                 delta= PIL_check_seconds_timer()-stime;
961                                 if (delta>5.0) break;
962                         }
963                         
964                         waitcursor(0);
965                         notice("%8.6f s/op - %6.2f ops/s - %d iterations", delta/a, a/delta, a);
966                         return 0;
967                 }
968                 else if(G.qual==(LR_ALTKEY|LR_CTRLKEY)) {
969                         int a;
970                         int event= pupmenu("10 Timer%t|draw|draw+swap|undo");
971                         if(event>0) {
972                                 double stime= PIL_check_seconds_timer();
973                                 char tmpstr[128];
974                                 int time;
975
976                                 waitcursor(1);
977                                 
978                                 for(a=0; a<10; a++) {
979                                         if (event==1) {
980                                                 scrarea_do_windraw(curarea);
981                                         } else if (event==2) {
982                                                 scrarea_do_windraw(curarea);
983                                                 screen_swapbuffers();
984                                         }
985                                         else if(event==3) {
986                                                 BIF_undo();
987                                                 BIF_redo();
988                                         }
989                                 }
990                         
991                                 time= (int) ((PIL_check_seconds_timer()-stime)*1000);
992                                 
993                                 if(event==1) sprintf(tmpstr, "draw %%t|%d ms", time);
994                                 if(event==2) sprintf(tmpstr, "d+sw %%t|%d ms", time);
995                                 if(event==3) sprintf(tmpstr, "undo %%t|%d ms", time);
996                         
997                                 waitcursor(0);
998                                 pupmenu(tmpstr);
999
1000                         }
1001                         return 0;
1002                 }
1003                 break;
1004                                 
1005         case UKEY:
1006                 if(textediting==0) {
1007                         if(G.qual==LR_CTRLKEY) {
1008                                 if(okee("Save user defaults")) {
1009                                         BIF_write_homefile();
1010                                 }
1011                                 return 0;
1012                         }
1013                         else if(G.qual==LR_ALTKEY) {
1014                                 if(curarea->spacetype!=SPACE_TEXT) {
1015                                         BIF_undo_menu();
1016                                         return 0;
1017                                 }
1018                         }
1019                 }
1020                 break;
1021                 
1022         case WKEY:
1023                 if(textediting==0) {
1024                         if(G.qual==LR_CTRLKEY) {
1025                                 strcpy(dir, G.sce);
1026                                 if (untitled(dir)) {
1027                                         activate_fileselect(FILE_BLENDER, "Save File", dir, BIF_write_file);
1028                                 } else {
1029                                         BIF_write_file(dir);
1030                                         free_filesel_spec(dir);
1031                                 }
1032                                 return 0;
1033                         }
1034                         else if(G.qual==LR_ALTKEY) {
1035                                 write_videoscape_fs();
1036                         }
1037                 }
1038                 break;
1039                 
1040         case XKEY:
1041                 if(textspace==0 && textediting==0) {
1042                         if(G.qual==LR_CTRLKEY) {
1043                                 if(okee("Erase all")) {
1044                                         if( BIF_read_homefile()==0) error("No file ~/.B.blend");
1045                                 }
1046                                 return 0;
1047                         }
1048                 }
1049                 break;
1050         case YKEY:      // redo alternative
1051                 if(textspace==0) {
1052                         if(G.qual==LR_CTRLKEY) {
1053                                 BIF_redo(); 
1054                                 return 0;
1055                         }
1056                 }
1057                 break;
1058         case ZKEY:      // undo
1059                 if(textspace==0) {
1060                         if(G.qual & (LR_CTRLKEY|LR_COMMANDKEY)) { // all combos with ctrl/commandkey are accepted
1061                                 if ELEM(G.qual, LR_CTRLKEY, LR_COMMANDKEY) BIF_undo();
1062                                 else BIF_redo(); // all combos with ctrl is redo
1063                                 return 0;
1064                         }
1065                 }
1066                 break; 
1067         }
1068         
1069         return 1;
1070 }
1071
1072 /* eof */